package com.baosight.risk.common.file;

import com.baosight.risk.common.utils.ReadProperties;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.Calendar;
import java.util.Random;

/**
 * 作者： lishaoqing
 * 时间： 2019年07月10日
 * 描述： FileManager
 * 版本: v1.0
 */
@Component
public class FileManager {

    /**
     * 磁盘存储路径根目录
     */
    private final String ROOT_PATH = ReadProperties.getValueString("projectServerFilePath");

    /**
     * 随机数生成器
     */
    private Random random = new Random();

    public String saveFile(Config config) throws Exception {
        generateDir(config);
        String filePath = "";
        if (config.defaultFilename) {
            filePath = generateFileName(config);
        } else {
            filePath = validName(config);
            streamToFile(getReader(config), getWriter(filePath));
        }
        return filePath;
    }

    public File getFIle(String filepath) {
        File f = new File(filepath);
        return f;
    }

    public BufferedReader getReader(Config config) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(config.inputStream, config.encode));
        return br;
    }

    public BufferedWriter getWriter(Config config) throws Exception {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(config.outputStream, config.encode));
        return bw;
    }

    public BufferedReader getReader(String filepath) throws Exception {
        File f = new File(filepath);
        BufferedReader br = new BufferedReader(new FileReader(f));
        return br;
    }

    public BufferedWriter getWriter(String filepath) throws Exception {
        File f = new File(filepath);
        BufferedWriter br = new BufferedWriter(new FileWriter(f));
        return br;
    }

    public void closeReader(BufferedReader reader) throws Exception {
        reader.close();
    }

    public void closeWriter(BufferedWriter writer) throws Exception {
        writer.flush();
        writer.close();
    }

    public void streamToFile(BufferedReader reader, BufferedWriter writer) throws Exception {
        String line = null;
        while ((line = reader.readLine()) != null) {
            writer.write(line);
            writer.write("\r\n");
            writer.newLine();
            writer.flush();
        }
        closeReader(reader);
        closeWriter(writer);
    }

    /**
     * 默认文件名生成规则
     */
    public String generateFileName(Config config) {
        String name = "" + (random.nextInt() + 111 + random.nextInt() + 555) + System.currentTimeMillis() + (random.nextInt() + 666 + random.nextInt() + 999) + config.suffix;
        return config.filePath + "/" + name;
    }

    /**
     * 自定义prefix(1)(2)(3)命名规则解决文件名重复的问题
     */
    public String validName(Config config) {
        String valid = config.filePath + "/" + config.filename;
        String filename = config.filename;
        String result = "";
        String prefix = "";
        String suffix = "";
        //截取文件名和后缀
        int indx = filename.lastIndexOf(".");
        if (indx > 0 && indx < filename.length() - 1) {
            prefix = filename.substring(0, indx);
            suffix = filename.substring(indx, filename.length());
        }
        File file = new File(config.filePath + "/" + filename);
        String regex = prefix.replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)") + "\\(\\d+\\)+";
        int maxId = 0;
        //判断是否存在重名文件
        if (file.exists()) {
            String[] list = file.getParentFile().list();
            String maxprefix = prefix + "(0)";
            for (String tmpprefix : list) {
                tmpprefix = tmpprefix.substring(0, tmpprefix.lastIndexOf("."));
                if (tmpprefix.matches(regex)) {
                    int id = Integer.parseInt(tmpprefix.substring(tmpprefix.lastIndexOf("(") + 1, tmpprefix.lastIndexOf(")")));
                    maxId = Integer.parseInt(maxprefix.substring(maxprefix.lastIndexOf("(") + 1, maxprefix.lastIndexOf(")")));
                    if (id > maxId) {
                        maxprefix = tmpprefix;
                        maxId = id;
                    }
                }
            }
            //重命名文件
            if (maxprefix.equals(prefix)) {
                result = prefix + "(" + 1 + ")" + suffix;
            } else {
                result = prefix + "(" + (maxId + 1) + ")" + suffix;
            }
            config.filename = result;
            valid = config.filePath + "/" + result;
        }
        valid = valid.replaceAll("//", "/").replaceAll("\\\\", "/");
        return valid;
    }

    /**
     * 年/月/日的格式生成文件夹
     */
    public String generateDir(Config config) {
        String businessPath = ROOT_PATH + "/" + config.businessCode;
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int date = calendar.get(Calendar.DATE);
        String dirPath = businessPath + "/" + year + "/" + month + "/" + date + "/";
        config.filePath = dirPath;
        File dir = new File(dirPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        dirPath = dirPath.replaceAll("//", "/").replaceAll("\\\\", "/");
        return dirPath;
    }

    /**
     * 获取文件后缀名
     * @param filename 文件名
     * @return 后缀名
     */
    public String getFileType(String filename){
        String fileType = "file";
        int indx = filename.lastIndexOf(".");
        if (indx > 0 && indx < filename.length() - 1) {
            fileType = filename.substring(indx + 1).toLowerCase();
        }
        return fileType;
    }

    public Config getConfig() {
        return new Config();
    }

    @Data
    public class Config {
        /**
         * 业务编码
         */
        private String businessCode;
        /**
         * 文件名
         */
        private String filename;
        /**
         * 文件名后缀
         */
        private String suffix = ".txt";
        /**
         * 是否使用系统生成的文件名
         */
        private boolean defaultFilename;
        /**
         * 要保存的文件地址
         */
        private String filePath;
        /**
         * 要保存的文件流
         */
        private InputStream inputStream;
        /**
         * 要输出的文件流
         */
        private OutputStream outputStream;
        /**
         * 字符集
         */
        private String encode = "UTF-8";
    }


//    public static void main(String[] args) {
//        try {
//            FileManager fileManager = new FileManager();
//            FileManager.Config config = fileManager.getConfig();
//            config.setBusinessCode("test");
//            config.setFilename("aaa.txt");
//            FileInputStream fin = new FileInputStream(new File("F:\\M0001.xml"));
//            config.setInputStream(fin);
//
//            fileManager.saveFile(config);
//        }catch (Exception e){
//            log.error(e.getMessage());
//        }
//
//    }


}
